const { ccclass, property } = cc._decorator;

@ccclass
export default class FramesPlayer extends cc.Component {

    @property(cc.Integer)
    fps: number = 6;

    @property(cc.Boolean)
    loop: boolean = true;

    @property(cc.Boolean)
    autoPlay: boolean = true;

    @property(cc.SpriteFrame)
    frames: cc.SpriteFrame[] = [];

    private canPlayOnStart = true;
    private hasCallStop = false;
    private onFinish: Function;
    isPlaying = false;

    start() {
        if (this.canPlayOnStart && this.autoPlay && !this.hasCallStop) {
            this.play();
        }
    }

    play(startFrameIndex = 0) {
        this.hasCallStop = false;
        this.isPlaying = true;
        let sprite = this.getComponent(cc.Sprite);
        let interval = 1 / this.fps;
        let repeat = this.loop ? cc.macro.REPEAT_FOREVER : this.frames.length - 1;
        let frameIndex = startFrameIndex;
        let frameLength = this.frames.length;
        this.unscheduleAllCallbacks();
        this.schedule(() => {
            sprite.spriteFrame = this.frames[frameIndex];
            frameIndex += 1;
            if (frameIndex >= frameLength) {
                frameIndex = 0;
                if (this.onFinish) {
                    this.onFinish();
                }
            }
        }, interval, repeat, 0);
    }

    stop(stopFrameIndex?: number) {
        this.hasCallStop = true;
        this.isPlaying = false;
        this.unscheduleAllCallbacks();
        if (stopFrameIndex != undefined && stopFrameIndex < this.frames.length) {
            let sprite = this.getComponent(cc.Sprite);
            sprite.spriteFrame = this.frames[stopFrameIndex];
        }
    }

    /**
     * 播放序列帧
     * @param frameNames SpriteFrame的名字序列
     * @param fps 默认6
     * @param loop 默认true
     */
    static play(target: cc.Node, atlas: cc.SpriteAtlas, frameNames: string[], fps: number = 6, loop: boolean = true, onFinish?: Function) {
        let player: FramesPlayer = target.getComponent(FramesPlayer);
        if (!player) {
            player = target.addComponent(FramesPlayer);
        }
        player.canPlayOnStart = false;
        player.frames = [];
        for (let i = 0; i < frameNames.length; i++) {
            player.frames.push(atlas.getSpriteFrame(frameNames[i]));
        }
        player.fps = fps;
        player.loop = loop;
        player.onFinish = onFinish;
        player.play();
    }

    /**
     * 停止播放
     */
    static stop(target: cc.Node, stopFrameIndex?: number) {
        let player: FramesPlayer = target.getComponent(FramesPlayer);
        if (!player) {
            player = target.addComponent(FramesPlayer);
        }
        player.stop(stopFrameIndex);
    }

}
